﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using dotnetCHARTING.WinForms;
using Processing001.Library.AbstractClasses;
using Processing001.Library.Interfaces;

namespace Processing001.Library
{
    public class Solution001 : SolutionAbstract<ComplexNumber, Graphic>
    {
        public Solution001(int size)
        {
            this.size = size;

            thread = new Thread(new ThreadStart(StartProcess));
            output = new List<ComplexNumber>();
        }

        private void Initialize()
        {
            DefaultGenerator generator = new DefaultGenerator(size);
            output = generator.Generate();
            input = generator.Input;
        }

        private void StartProcess()
        {
            graphics.Clear();

            Initialize();

            FirstStep();
            SecondStep();
            ThirdStep();

            if (DisplayGraphics != null)
            {
                DisplayGraphics(this, EventArgs.Empty);
            }
        }

        private void FirstStep()
        {
            Chart chart = GenerateChartByTask(Graphic.Left, "Real", output, input, SeriesType.Line);
            graphics.Add(Graphic.Real, chart);
        }

        Chart CreateChart(String title, SeriesType type)
        {
            Chart chart = new Chart();
            chart.Title = title;
            chart.Type = ChartType.Scatter;
            chart.Use3D = false;
            chart.Series.DefaultElement.Color = Color.FromArgb(49, 255, 49);
            chart.DefaultSeries.Type = type;
            chart.DefaultSeries.DefaultElement.Marker.Type = ElementMarkerType.None;
            chart.DefaultSeries.DefaultElement.Transparency = 0;
            chart.XAxis.Label.Text = "X";
            chart.YAxis.Label.Text = "Y";
            chart.TempDirectory = "temp";
            chart.Width = 600;
            chart.Height = 350;
            chart.Dock = DockStyle.Fill;
            return chart;
        }

        private Chart GenerateChartByTask(Graphic graphic, String title, 
            List<ComplexNumber> generatedValues, List<ComplexNumber> x, SeriesType type)
        {
            Chart chart = CreateChart(title, type);
            Series series = new Series();
            series.Name = "Series";
            for (int iterator = 0; iterator < generatedValues.Count; iterator++)
            {
                Element element = new Element(iterator.ToString());
                element.Name = "Element" + iterator.ToString();
                element.XValue = x[iterator].Real;
                element.YValue = generatedValues[iterator].Real;
                series.AddElements(element);
            }
            SeriesCollection collection = new SeriesCollection(series);
            chart.SeriesCollection.Add(collection);
            return chart;
        }

        private void SecondStep()
        {
            FurieWrapper wrapper = new FurieWrapper(size);
            List<ComplexNumber> generatedValues = wrapper.GenerateByWay(Way.Right, output);

            Values.Clear();
            Values.AddRange(generatedValues);

            if(ValuesUpdate != null)
            {
                ValuesUpdate(this, EventArgs.Empty);
            }

            Chart chart = CreateChart("Cos", SeriesType.Bar);
            Series series = new Series();
            series.Name = "Series";
            for (int iterator = 0; iterator < generatedValues.Count; iterator++)
            {
                Element element = new Element(iterator.ToString());
                element.Name = "Element" + iterator.ToString();
                element.XValue = input[iterator].Real;
                element.YValue = generatedValues[iterator].Real;
                series.AddElements(element);
            }
            SeriesCollection collection = new SeriesCollection(series);
            chart.SeriesCollection.Add(collection);

            graphics.Add(Graphic.Cos, chart);

            chart = CreateChart("Sin", SeriesType.Bar);
            series = new Series();
            series.Name = "Series";
            for (int iterator = 0; iterator < generatedValues.Count; iterator++)
            {
                Element element = new Element(iterator.ToString());
                element.Name = "Element" + iterator.ToString();
                element.XValue = input[iterator].Real;
                element.YValue = generatedValues[iterator].Image;
                series.AddElements(element);
            }
            collection = new SeriesCollection(series);
            chart.SeriesCollection.Add(collection);
            this.generatedValues = generatedValues;

            graphics.Add(Graphic.Sin, chart);
        }

        private void ThirdStep()
        {
            FurieWrapper wrapper = new FurieWrapper(size);
            List<ComplexNumber> result = wrapper.GenerateByWay(Way.Left, generatedValues);
            Chart chart = GenerateChartByTask(Graphic.Left, "Left", result, input, SeriesType.Line);
            graphics.Add(Graphic.Left, chart);
        }
    }
}
